#include "GUIManager.h"
#include "LuaInterface.h"
extern "C"
{
#include "lua.h"
}

GUIManager::GUIManager() : guiRenderer(0), guiSystem(0)
{
}

void GUIManager::initialise()
{
    guiRenderer = &CEGUI::OgreRenderer::bootstrapSystem();
    CEGUI::LuaScriptModule *scriptModule = &CEGUI::LuaScriptModule::create();
    scriptModule->setDefaultResourceGroup("Scripts");
    luaState = scriptModule->getLuaState();
    tolua_Interface_open(luaState);
    guiSystem = CEGUI::System::getSingletonPtr();
    guiSystem->setScriptingModule(scriptModule);
    guiSystem->executeScriptFile("init.lua");
}

bool GUIManager::executeScript(std::string script)
{
    try
    {
        guiSystem->executeScriptFile(script);
        return true;
    }
    catch(CEGUI::GenericException &e)
    {
        return false;
    }
}

std::string GUIManager::getLuaString(std::string name)
{
    lua_getglobal(luaState,name.c_str());
    const char *r = lua_tostring(luaState,1);
    std::string result = (r==NULL)?"":r;
    lua_pop(luaState,1);
    return result;
}

void GUIManager::update(float t)
{
    guiSystem->injectTimePulse(t);
}

void GUIManager::setWindowSize(int w, int h)
{
    guiRenderer->setDisplaySize(CEGUI::Size(w,h));
    guiSystem->notifyDisplaySizeChanged(CEGUI::Size(w,h));
}

bool GUIManager::keyPressed(const OIS::KeyEvent &evt)
{
    guiSystem->injectKeyDown(evt.key);
    guiSystem->injectChar(evt.text);
    return true;
}

bool GUIManager::keyReleased(const OIS::KeyEvent &evt)
{
    guiSystem->injectKeyUp(evt.key);
    return true;
}

bool GUIManager::mouseMoved(const OIS::MouseEvent &evt)
{
    if (CEGUI::MouseCursor::getSingletonPtr()->isVisible())
    {
        guiSystem->injectMouseMove((float)evt.state.X.rel,(float)evt.state.Y.rel);
        if (evt.state.Z.rel) guiSystem->injectMouseWheelChange(evt.state.Z.rel/120.0f);
    }
    return true;
}

bool GUIManager::mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID id)
{
    if (CEGUI::MouseCursor::getSingletonPtr()->isVisible())
        guiSystem->injectMouseButtonDown(convertMouseButton(id));
    return true;
}

bool GUIManager::mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID id)
{
    if (CEGUI::MouseCursor::getSingletonPtr()->isVisible())
        guiSystem->injectMouseButtonUp(convertMouseButton(id));
    return true;
}

CEGUI::MouseButton GUIManager::convertMouseButton(OIS::MouseButtonID id)
{
    switch (id)
    {
    case OIS::MB_Left:
        return CEGUI::LeftButton;
    case OIS::MB_Right:
        return CEGUI::RightButton;
    case OIS::MB_Middle:
        return CEGUI::MiddleButton;
    default:
        return CEGUI::LeftButton;
    }
}
